<?php

class Default_Model_Tracks extends Zend_Db_Table_Abstract {

	protected $_name = 'tracks';
	protected $_primary = array('id');
	protected $_cols = array(
		'id',
		'guid',
		'name',
		'users_id',
		'datetime',
		'path',
		'time',
		'encoded_points',
		'encoded_levels'
	);
	
	/**
	 * Optymalizuje ścieżkę
	 * 
	 * @param array $track Tablica z punktami i czasem
	 * @return array
	 */
	protected function _optimize($track)
	{
		if (!is_array($track))
			return false;
		
		$pos = array();
		foreach ($track as $point) {
			if (!isset($point['latitude']) || !isset($point['longitude']) || !isset($point['time']))
				return false;

			if (!isset($point['ns'])) {
				$point['ns'] = 'N';
			}
			if (!isset($point['ew'])) {
				$point['ew'] = 'E';
			}
			$latitude = ($point['ns'] == 'S' ? -1 : 1) * $point['latitude'];
			$longitude = ($point['ew'] == 'W' ? -1 : 1) * $point['longitude'];
			
			$pos[] = array(
				'x' => floatval($latitude),
				'y' => floatval($longitude),
				'time' => floatval($point['time'])
			);
		}
		$pos = Zend_Filter::filterStatic($pos, 'PolylineReducer', array('0.00005'), 'Core_Filter_Google_Maps');
		return $pos;
	}

	/**
	 * Sprawdza, czy sciezka o podanej nazwie istnieje w bazie
	 *
	 * @param string $name Nazwa sciezki
	 * @return bool
	 */
	public function trackIdExists($id)
	{
		if (!is_numeric($name) || $id <= 0) {
			return false;
		}

		return $this->select()
			->from($this->_name, array('id'))
			->where('"id" = ?', $name)
			->limit(1)
			->query()->fetch() !== false;
	}
	
	/**
	 * Sprawdza, czy sciezka o podanej nazwie istnieje w bazie
	 *
	 * @param string $name Nazwa sciezki
	 * @return bool
	 */
	public function trackGuidExists($name)
	{
		if (!is_string($name))
			return false;

		return $this->select()
			->from($this->_name, array('id'))
			->where('"guid" = ?', $name)
			->limit(1)
			->query()->fetch() !== false;
	}

	/**
	 * Dodawanie nowej ścieżki do bazy
	 *
	 * @param int $user Autor dodanej ścieżki
	 * @param array $track Tablica ze ścieżką
	 * @return int|false
	 */
	public function addTrack($user, $track)
	{
		$track = $this->_optimize($track);
		
		if (!is_array($track) || !is_numeric($user) || $user <= 0) {
			return false;
		}

		$filterGuid = new Zend_Filter();
		$filterGuid->addFilter(new Core_Filter_TitleURL(new Core_Validate_Exists($this, 'trackGuidExists')))
			->addFilter(new Core_Filter_Preamble(50));
		
		$encoded = Zend_Filter::filterStatic(
			$track,
			'Google_Maps_EncodePolyline',
			array(),
			'Core_Filter'
		);
		
		$path = $time = array();
		foreach ($track as $point) {
			$path[] = '(' . str_replace(',', '.', strval($point['x'])) . ', ' . str_replace(',', '.', strval($point['y'])) . ')';
			$time[] = $point['time'];
		}

		$name = new Zend_Date();
		$name = $name->getIso();
		return $this->insert(array(
			'users_id' => intval($user),
			'guid' => $filterGuid->filter($name),
			'name' => $name,
			'datetime' => new Zend_Db_Expr('date_part(\'epoch\', CURRENT_TIMESTAMP)::int'),
			'path' => implode(', ', $path),
			'time' => '{' . implode(', ', $time) . '}',
			'encoded_points' => $encoded['polyline'],
			'encoded_levels' => $encoded['levels']
		));
	}
	
	/**
	 * Pobiera informacje o wybranej sciezce
	 *
	 * @param id $trackId Id sciezki
	 * @param int $user ID użytkownika
	 * @return stdClass|false
	 */
	public function getTrackById($trackId, $user)
	{
		if (!is_numeric($user) || $user <= 0 ||
			!is_numeric($trackId) || $trackId <= 0)
			return false;

		return $this->select()
			->from($this->_name, $this->_cols + array('center' => new Zend_Db_Expr('point(polygon("path"))')))
			->where('"id" = ?', $trackId)
			->where('"users_id" = ?', $user)
			->limit(1)
			->query()->fetch();
	}

	/**
	 * Pobiera informacje o wybranej sciezce
	 *
	 * @param string $track Nazwa sciezki
	 * @param int $user ID użytkownika
	 * @return stdClass|false
	 */
	public function getTrack($track, $user = null)
	{
		if (!is_null($user) && (!is_numeric($user) || $user <= 0))
			return false;
		if (!preg_match('#^[a-z0-9_-]+$#i', $track))
			return false;

		$select = $this->select()
			->from($this->_name, $this->_cols + array('center' => new Zend_Db_Expr('point(polygon("path"))')))
			->where('"guid" = ?', $track)
			->limit(1);

		if (!is_null($user))
			$select->where('"users_id" = ?', $user);

		return $select
			->query()->fetch();
	}

	/**
	 * Pobiera listę ścieżek dla danego użytkownika
	 *
	 * @param int $user Autor dodanej ścieżki
	 * @return Zend_Paginator
	 */
	public function getTracks($user)
	{
		if (!is_numeric($user) || $user <= 0)
			return false;

		return Zend_Paginator::factory(
			$this->select()
				->from($this->_name, array('id', 'name', 'guid', 'datetime'))
				->where('"users_id" = ?', intval($user))
			);
	}
}